<?php


namespace app\socket\services;


use app\common\model\ClientModel;
use app\common\model\MessageLogModel;
use app\common\model\StaffModel;
use app\common\model\UserListModel;
use app\common\services\RedisService;
use GatewayWorker\Lib\Gateway;

class UserInfoService extends BaseService
{



    //  消息的发送 都是由 $client_id  来发送的  但是 用户的识别 是以 ticket  来识别的

    /**
     * 客服登录 保存客服信息
     * @param $ticket 用户凭证
     * @param $userInfo 用户数据
     */
    static function addKefu($connection,$userInfo){
        $client_id = $connection;

//        $uuid = self::$kefuRole .$userInfo['id'];
        $uuid = $userInfo['uuid'];

        //将 $client_id 和 uid 绑定起来
        Gateway::bindUid($client_id,$uuid);

        //获取当前房间内的人数
        $userInfo['hasNewMsg'] = Gateway::getUidCountByGroup(self::$roomKey.$uuid);

        $_SESSION['userinfo'] = $userInfo;

        $msg_data = [
            'type'=>'join',
            'userinfo'=> self::handleUserInfo($userInfo),
        ];

        //通知其他客服  我上线了
        Gateway::sendToGroup(self::$companyKey.$userInfo['admin_id'],json_encode($msg_data));

        //通知房间中的顾客 我回来了
        Gateway::sendToGroup(self::$roomKey.$uuid,json_encode($msg_data));

        //将客服 加入到 公司客服群
        Gateway::joinGroup($client_id, self::$companyKey.$userInfo['admin_id']);
        return true;
    }

    //存储 客户的个人信息
    static function addClient($connection,$userInfo){
//        $client_id = $connection->id;
        $client_id = $connection;
//        dump("我的个人信息===》");
//        dump($userInfo);
        $uuid = $userInfo['uuid'];
        //将 $client_id 和 uid 绑定起来
        Gateway::bindUid($client_id,$uuid);

        if($userInfo['to_id']){
            //加入指定的用户聊天
            $to_uuid = self::addUserRoom($userInfo);
        }else{
            //加入平台客服聊天
            $to_uuid = self::addKefuRoom($userInfo);
        }
//        dump('to_uuid===>'.$to_uuid);
        //将客户 加入到 聊天列表中
//        Gateway::joinGroup($client_id, self::$roomKey.$to_uuid);
        self::joinRoom($uuid,$to_uuid);

//        echo "12344";
        $_SESSION['userinfo'] = $userInfo;

//        //将顾客的信息 推送给客服
        $gukeMsg = [
            'type'=>'join',//加入会话
            'userinfo'=>self::handleUserInfo($userInfo,$to_uuid),//将自己的信息 发送给对方
        ];

        self::success($gukeMsg,$to_uuid);
        $ChatUser = ClientModel::getInfo($to_uuid);
//        dump("ChatUser");
//        dump($ChatUser);

        // 将 客服的信息 发送给自己
        self::success([
            'type'=>'ChatUser',
            'userinfo'=>self::handleUserInfo($ChatUser),
        ]);

        // 新用户进入  调用机器人新用户钩子
        RobotService::UserFirstWelcome();
    }

    /**
     * 加入到指定的用户房间
     * @param $userInfo
     */
    static function addUserRoom($userInfo){
        $info = ClientModel::findOne(['uid'=>$userInfo['to_id'],'role'=>2]);
        if(empty($info)){
            self::success(['type'=>'err','msg'=>'对方不存在，加入聊天失败！']);
            //自动转接给客服
            return self::addKefuRoom($userInfo);
        }
        return $info['id']; //  实际上也是等于uuid
    }

    /**
     * 加入到客服的房间中
     * @param $userInfo
     * @return mixed 返回客服对应的用户id
     */
    static function addKefuRoom($userInfo){
        //将客户 加入到 对方的群聊中
        $staffInfo = self::getStaffId($userInfo);
        if(!$staffInfo){
            self::success(['type'=>'err','msg'=>'对方不在线！']);
        }
//        dump('客服房间');
//        dump($staffInfo);
        $staffId = $staffInfo['staff_id']; //客服id
        $depart_id = $staffInfo['depart_id'];//客服组
        if(isset($staffInfo['uuid']) && !empty($staffInfo['uuid'])){
            $staffUUid= $staffInfo['uuid'];
        }else{
            $staffUUid= StaffModel::getUUid($staffId,$userInfo['admin_id']);
        }

        //如果有发生改变  则更新数据库的接待消息
        if($staffId != $userInfo['staff_id']){
            //将实际的接待人给记录下来
            $userInfo['staff_id'] = $staffId;
            //  更新数据库的接待信息
            ClientModel::updates(['id'=>$userInfo['id']],[
                'staff_id'=>$staffId,
                'depart_id'=>$depart_id,
            ]);
        }
        return $staffUUid;
    }

    // 获取在线的用户列表
    static function getUserList(){
        $userInfo = $_SESSION['userinfo'];
        $reData = [
            'type'=>'joinList',//批量加入列表
            'gukeList'=>[],
            'kefuList'=>[],
        ];
        $gukeIdList = []; //在线的列表

//        dump('====>5555');
        //顾客列表
        $gukeList = Gateway::getClientSessionsByGroup( self::$roomKey.$userInfo['uuid']);
        if(!empty($gukeList)){
            foreach ($gukeList as $client=>$item){
                $gukeIdList[] = $item['userinfo']['id'];
                $reData['gukeList'][] = self::handleUserInfo($item['userinfo']);
            }
        }

        //获取我的好友列表
        $offlineUserList = UserListModel::getMyUserList($userInfo['uuid']);
        if(!empty($offlineUserList)){
            foreach ($offlineUserList as $key=>$item){
                if(!in_array($item['id'],$gukeIdList)){
                    $myUserInfo = self::handleUserInfo($item);
                    $reData['gukeList'][] = $myUserInfo;
                    //如果我的好友在线  那么 我需要通知他 我上线了
                    if($myUserInfo['online']){
                        self::success([
                            'type'=>'join',
                            'userinfo'=>self::handleUserInfo($_SESSION['userinfo'],$myUserInfo['uuid']),
                        ],$myUserInfo['uuid']);

                        //为了方便通知  我需要进入他的房间   他需要进入我的房间
                        //互相加入房间中
                        self::joinRoom($_SESSION['userinfo']['uuid'],$myUserInfo['uuid']);

                        //为了方便通知


                    }
                }
            }
        }

        //二次清洗数据 将好友列表排序 按照 在线 消息 时间 进行排序
        usort($reData['gukeList'], function($a, $b) {
            if($a['online']!=$b['online']){
                return ($a['online']>$b['online']) ? -1:1;
            }else if($a['hasNewMsg']!=$b['hasNewMsg']){
                return ($a['hasNewMsg']>$b['hasNewMsg']) ? -1:1;
            }else {
                return ($a['last_id']>$b['last_id']) ? -1:1;
            }
        });

        //如果是客服 则获取客服列表
        if($userInfo['role']==1){
            //在线客服列表
            $kefuList = Gateway::getClientSessionsByGroup( self::$companyKey.$userInfo['admin_id']);
            if(!empty($kefuList)){
                foreach ($kefuList as $client=>$item){
                    $reData['kefuList'][] = self::handleUserInfo($item['userinfo']);
                }
            }
        }

        //返回给用户
        self::success($reData);
    }



    //获取 接待的客服号牌
    static private function getStaffId($userInfo){
        //如果存在 指定的 客服 则 直接返回指定客服
        $to_uuid = StaffModel::getUUid($userInfo['staff_id'],$userInfo['admin_id']);
        //如果指定了客服  并且 客服在线
        if($to_uuid && $userInfo['staff_id'] && Gateway::isUidOnline($to_uuid)){
            return [
                'staff_id'=>$userInfo['staff_id'],
                'uuid'=>$to_uuid,
                'depart_id'=>$userInfo['depart_id'],
            ];
        }

//        //获取在线客服列表
        $list = Gateway::getClientSessionsByGroup( self::$companyKey.$userInfo['admin_id']);
//        dump('在线客服列表');
//        dump($list);
        //客服都不在线  选择默认离线客服 做会话记录留言
        if(empty($list)){
            $ret  = self::offline($userInfo);
            return $ret;
        }

        $new_list = [];
        $new_list_max = [];
        foreach ($list as $client_id =>$item){
            $iteminfo = $item['userinfo'];//获取客服的个人用户信息
//            dump("item--->ID：{$iteminfo['id']} 姓名：{$iteminfo['name']} 客服组：{$iteminfo['depart_id']}");
//            dump($item);
            /**
             *   "userinfo" => array:11 [
                        "id" => 1
                        “uuid”=>123445,
                        "admin_id" => 1
                        "depart_id" => "1"
                        "name" => "兔子"
                        "mobile" => "18324234933"
                        "head" => "/uploads/20200318/137b548c5ece2e8efc3dfa54c0b3f7e1.png"
                        "priority" => 1
                        "work_status" => 1
                        "online" => 1626143953
                        "getDepartment" => array:8 [
                                "id" => 1
                                "admin_id" => 1
                                "name" => "小帮手客服"
                                "number" => 1
                                "status" => 1
                                "priority" => 99
                                "create_time" => "2021-07-13 09:08:33"
                                "update_time" => "2021-07-13 09:12:42"
                                ]
                        "role" => 1
                        ]

             */
            $new_list_max[] = $iteminfo;
            if($userInfo['depart_id']){
                if($iteminfo['depart_id'] == $userInfo['depart_id'])
                    $new_list[$client_id] = $iteminfo;
            }else{
                $new_list[$client_id] = $iteminfo;
            }
        }
//        dump('$new_list');
//        dump($new_list);
        //没有合适的客服 在在线客服中筛选一个进行接待
        if(empty($new_list)){
            $new_list = $new_list_max;
        }
        $number = count($new_list);
        //只有一个 直接返回
        if($number==1){
            // depart_id
            $iteminfo = array_shift($new_list);
        }else{
            $index = self::_hashId(mt_rand(),$number-1);
            $iteminfo = array_values($new_list)[$index];
        }

        return [
            'staff_id'=>$iteminfo['id'],
            'depart_id'=>$iteminfo['depart_id'],
        ];
    }

    /**
     * 给当前分组中的某个人 设置个人信息
     * @param $staffId  房间ID
     * @param $field   字段名
     * @param $value   字段值
     */
    static function setSessionData($uid,$field,$value){
        $uuid = self::$kehuRole.$uid;
//        dump($uuid);exit;
        $list = Gateway::getClientIdByUid($uuid);
//        $list = Gateway::getClientIdByUid(self::getUUid($uid));
//        dump(self::getUUid($uid));exit;
//        dump($list);exit;
        foreach ($list as $client_id){
            $session = Gateway::getSession($client_id);
            $session['userinfo'][$field] = $value;
            Gateway::updateSession($client_id, $session);
//            Gateway::setSession($client_id,$session);
        }
        return true;

    }

    //获取离线客服
    private static function offline($userInfo){
        $admin_id = $userInfo['admin_id'];
        $depart_id = $userInfo['depart_id']?:0;
        $staff_id = $userInfo['staff_id']?:0;
        $where = [
            'admin_id'=>$admin_id,
            'status'=>1,
//            'role'=>1,
        ];
        $order = "priority desc,online desc";
        $list = StaffModel::findAll($where,"id,depart_id",$order,1);
//        dump('离线客服列表');
//        dump($list);

        if($list){
            $depa_arr = [];
            //返回符合条件的客服
            foreach ($list as $k=>$v){
                if($staff_id && $staff_id == $v['id']){
//                    return $v['id'];
                    return [
                        'staff_id'=>$v['id'],
                        'depart_id'=>$v['depart_id'],
                    ];
                }
                if($depart_id == $v['depart_id']){
                    $depa_arr[] = [
                        'staff_id'=>$v['id'],
                        'depart_id'=>$v['depart_id'],
                    ];
                }
            }
            $depa_count = count($depa_arr);
            if($depa_count>0){
                return $depa_arr[mt_rand(0,$depa_count-1)];
            }else{
                $inx = mt_rand(0,count($list)-1);
                $iteminfo = $list[$inx];
                return [
                    'staff_id'=>$iteminfo['id'],
                    'depart_id'=>$iteminfo['depart_id'],
                ];
            }
        }else{
            return 0;
        }

    }

    /**
     * 根据ID 得到hash 后 0-m-1之间 的值
     * @param $id
     * @param $m
     */
    private static function _hashId($id,$m){
        $k = md5($id);
        $l = strlen($k);
        $b = bin2hex($k);
        $h=0;
        for ($i=0;$i<$l;$i++){
            $h+=substr($b,$i*2,2);
        }
        $hash = ($h*1)%$m;
        return $hash;
    }

}